﻿using LxBasic;

namespace LxLESS
{
    public class BiCGStabZone
    {
        public double[] r0;
        public double[] r;//s也用r存储
        public double[] p;
        public double[] v;
        public double[] y;
        public double[] z;
        public double[] t;
        public void CheckCrete(int length, List<double[]> shareArr)
        {
            int i = 0;
            check(ref r);
            check(ref r0);
            check(ref p);
            check(ref v);
            check(ref y);
            check(ref z);
            check(ref t);
            void check(ref double[] target)
            {
                if (shareArr != null && i < shareArr.Count && shareArr[i].Length >= length)
                {
                    target = shareArr[i];
                }
                else
                {
                    CheckCreator.ArrayStrict(ref target, length);
                }
                i++;
            }
        }

        public void BiCGStab_Cal_xArray(IndexRange indexNumber, double[] x, ThreadInfo threadInfo)
        {
            double alpha = BiCGStabGlobal.alpha, omega = BiCGStabGlobal.omega;
            (int i1, int endp1) = indexNumber.Split(threadInfo);
            for (; i1 < endp1; i1++)
            {
                x[i1] += alpha * y[i1] + omega * z[i1];
            }
        }
        public void BiCGStab_JacPrec_Ini_r0_pArray_yArray(IndexRange indexNumber, double[] ADiag, ThreadInfo threadInfo)
        {
            (int i1, int endp1) = indexNumber.Split(threadInfo);
            for (; i1 < endp1; i1++)
            {
                double pt = r0[i1] = p[i1] = r[i1];
                y[i1] = pt / ADiag[i1];
            }
        }
        public void BiCGStab_JacPrec_sArray_zArray(IndexRange indexNumber, double[] ADiag, ThreadInfo threadInfo)
        {
            double alpha = BiCGStabGlobal.alpha;
            (int i1, int endp1) = indexNumber.Split(threadInfo);
            for (; i1 < endp1; i1++)
            {
                ref double rref = ref r[i1];
                rref -= alpha * v[i1];
                z[i1] = rref / ADiag[i1];
            }
        }
        public void BiCGStab_rArray_rho1(IndexRange indexNumber, ThreadInfo threadInfo)
        {
            double omega = BiCGStabGlobal.omega;
            (int i1, int endp1) = indexNumber.Split(threadInfo);
            Float128 temp = new();
            for (; i1 < endp1; i1++)
            {
                ref double rt = ref r[i1];
                rt -= omega * t[i1];
                temp += (r0[i1] * rt);
            }
            ThreadsMath.MemoryAdd(temp);
        }
        public void BiCGStab_JacPrec_pArray_yArray(IndexRange indexNumber, double[] ADiag, ThreadInfo threadInfo)
        {
            double beta = BiCGStabGlobal.beta; double omega = BiCGStabGlobal.omega;
            (int i1, int endp1) = indexNumber.Split(threadInfo);
            for (; i1 < endp1; i1++)
            {
                ref double pt = ref p[i1];
                pt = r[i1] + beta * (pt - omega * v[i1]);
                y[i1] = pt / ADiag[i1];
            }
        }
    }
}
//public void CheckCrete(int length, double[] rShare = null, double[] r0Share = null, double[] pShare = null, double[] vShare = null, double[] yShare = null, double[] zShare = null, double[] tShare = null)
//{
//    check(ref r, rShare, length);
//    check(ref r0, r0Share, length);
//    check(ref p, pShare, length);
//    check(ref v, vShare, length);
//    check(ref y, yShare, length);
//    check(ref z, zShare, length);
//    check(ref t, tShare, length);
//}
//private void check(ref double[] target, double[] shareArray, int length)
//{
//    if (shareArray != null && shareArray.Length >= length)
//    {
//        target = shareArray;
//    }
//    else
//    {
//        CheckCreator.ArrayStrict(ref target, length);
//    }
//}